using System;
using System.Text;
using System.Threading;
using System.Collections;
using MineFlagger;
using System.Drawing;

namespace MineFlagger {


	public class BaseCell {
		public Cell cell;
		public PathList Paths;
		public bool ValidTermination;


		public BaseCell (Cell cell) {
			this.cell = cell;
		}

		public Path this[int index] {
			get {
				return (Path)Paths[index]; 
			}
		}

	}

	public class CellFCellPair {
		public FlaggedCell FCell;
		public Cell Cell;

		public CellFCellPair(Cell cell, FlaggedCell fCell) {
			this.FCell = fCell;
			this.Cell = cell;
		}

		public override bool Equals(object obj) {
			return this.Cell.Equals(obj);
		}

        public override int GetHashCode()
        {
            throw new NotSupportedException();
        }
	}

	public class FlaggedCell : Cell {
		public ArrayList BaseCells;
		private Cell cell;

		public bool ConfoundsAnalysisPreformed = false;
		public bool AllNeighborsFulfilled = false;

		public FlaggedCell(Cell cell) : base(-1, -1) {	
			BaseCells = new ArrayList();
			this.cell = cell;
		}

		public override bool SuppressDrawing {
			get { return cell.SuppressDrawing; }
			set { cell.SuppressDrawing = value; }
		}

		public override bool Depressed {
			get { return cell.Depressed; }
			set { cell.Depressed = value; }
		}

		public override int NeighboringMines {
			get {
				return cell.NeighboringMines;
			}
		}

		public override bool Marked {
			get { return cell.Marked; }
			set { cell.Marked = value; }
		}

		public override Color MarkColor {
			get { return cell.MarkColor; }
			set { cell.MarkColor = value; }
		}

		
		public override CellState CellState {
			get { return cell.CellState; }
			set {
				cell.CellState = value;
			}
		}

		public override int X {
			get { return cell.X; }
		}

		public override int Y {
			get { return cell.Y; }
		}
	
		public override int CompareTo(object obj) {
			return cell.CompareTo(obj); 
		}

		public override bool Equals(Object obj) {
			return cell.Equals(obj);
		}
        public override int GetHashCode()
        {
            throw new NotSupportedException();
        }

		public override string ToString() {
			return cell.ToString();
		}

	}

	public class TreeControler {

		public TreeControler() {}


//		public BaseCell FillBase(BaseCell bCell, int maxPaths, int levels) {
//			
//			// Get all valid paths (and hook up)
//
//			// If levels <= 1, dont go any further
//
//			// If more then limit of paths, dont go any further 
//			// (my need to indicate with a flag that while the tree is not filled
//			//  out beond this point, the posobilities still exsist)
//
//			// Foreach path in Paths
//				// Foreach FlaggedCell in path
//					// Get all unfufiled niegboring cells
//					// Foreach unfufiled niegboring cell
//						//BaseCell newBCell = new BaseCell();
//						//newBCell = FillBase(newBCell, levels - 1);
//						// If newBCell has > 0 (valid) paths
//							// Hook up to flagged cell
//							// Also consider hooking up to bCell (or keep track of total?)
//
//			// return bCell
//		}

	}

	public class FillBaseDecision {
		private PathList pathList;
		private BaseCell baseCell;
		private ArrayList hiddenNeighbors;
		
		private float mineUncoverProb; // The probability on of the hidden nieghboring cells is a mine
		private float pathFlagProb; // The probabilty a given path is the corect path

		public FillBaseDecision(BaseCell baseCell, GameBoard gameBoard) {
			this.pathList = baseCell.Paths;
			this.baseCell = baseCell;

			pathFlagProb = 1f / pathList.Count;
			
			hiddenNeighbors = gameBoard.GetHiddenNeighbors(baseCell.cell);

			mineUncoverProb = (float)baseCell.cell.NeighboringMines / (float)hiddenNeighbors.Count;
		}

		public float MineUncoverProb { get { return mineUncoverProb; } }
		public float PathFlagProb { get { return pathFlagProb; } }
		
		public ArrayList HiddenNeighbors { get { return hiddenNeighbors; } }
		public PathList PathList { get { return pathList; } }
		public BaseCell BaseCell { get { return baseCell; } }
		

	}

}